/***********************************************
 **** 版权声明处 **
 ****  为了方便阅读和维护，请严格遵守相关代码规范，谢谢   ****
 *******************************************/
package bpm.graphic
{
	import flash.display.DisplayObject;
	import flash.geom.Rectangle;

	/*******************************************
	 **** huangjixin,2012-11-15,上午9:32:47 **
	 **** 请一句话表述该类主要作用  **
	 *******************************************/
	
	/**
	 *Node类是所有元素的基类，它继承自SkinnableContainer。
	 * <p>它除了拥有所有SkinnableContainer的属性，还有以下的标签属性:label和isSelected</p> 
	 * @author huangjixin
	 * 
	 */
	public class Node extends Renderer
	{
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 类私有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：private static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 类公有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：public static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 私有变量声明处，请以“_”开头定义变量
		// 例如：private var _example:String;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		private var _label:String = "Node";

		private var _centerX:Number;
		
		private var centerY:Number;
		
		private var _movable:Boolean = true;
		
		private var _ports : Vector.<PortBase>;
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 公有变量声明处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 构造函数，初始化相关工作可以放在里面
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		/**
		 *  Node构造函数。
		 * 
		 */
		public function Node()
		{
			super();
			
			ports = new Vector.<PortBase>();
		}//构造函数结束
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// getter和setter函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		[Bindable]
		/**
		 * label属性是显示在节点上面的文字属性。
		 * @return 
		 * 
		 */
		public function get label():String
		{
			return _label;
		}
		
		public function set label(value:String):void
		{
			_label = value;
		}

		public function get centerX():Number
		{
			return _centerX;
		}

		public function set centerX(value:Number):void
		{
			_centerX = value;
		}

		public function get movable():Boolean
		{
			return _movable;
		}
		
		public function set movable(value:Boolean):void
		{
			_movable = value;
		}
		
		public function get ports():Vector.<PortBase>
		{
			return _ports;
		}
		
		public function set ports(value:Vector.<PortBase>):void
		{
			_ports = value;
		}
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 相关事件响应函数和逻辑函数存放处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		public function addPort(port:PortBase, index:int = -1):void{
			ports.push(port);
		}
		
		public function getIncomingLinks():Vector.<Link>{
			var incomingLinks:Vector.<Link> = new Vector.<Link>();
			for each (var portBase:PortBase in ports) 
			{
				for each (var link:Link in portBase.links) 
				{
					if(link.endNode == this){
						incomingLinks.push(link);
					}
				}
				
			}
			return incomingLinks;
		}
		
		public function getIncomingLinksCount():int{
			return getIncomingLinks().length;
		}
		
		public function getLinks():Vector.<Link>{
			var incomingLinks:Vector.<Link> = getIncomingLinks();
			var outgoingLinks:Vector.<Link> = getOutgoingLinks();
			for each (var link:Link in incomingLinks) 
			{
				outgoingLinks.push(link);
			}
			return outgoingLinks;
		}
		
		public function getLinksCount():int{
			return getLinks().length;
		}
		
		public function getNodeOrBaseBounds(targetCoordinateSpace:DisplayObject):Rectangle{
			return getRect(targetCoordinateSpace);
		}
		
		public function getOutgoingLinks():Vector.<Link>{
			var outcomingLinks:Vector.<Link> = new Vector.<Link>();
			for each (var portBase:PortBase in ports) 
			{
				for each (var link:Link in portBase.links) 
				{
					if(link.endNode == this){
						outcomingLinks.push(link);
					}
				}
				
			}
			return outcomingLinks;
		}
		
		public function getOutgoingLinksCount():int{
			return getOutgoingLinks().length;
		}
		
		public function getPort(id:Object):PortBase{
			for each (var portBase:PortBase in portBase) 
			{
				if(portBase.id == id){
					return portBase;
				}
			}
			return null;
		}
		
		public function getPortCount():int{
			return ports.length;
		}
		
		public function removePort(port:PortBase):void{
			var length:int = ports.length;
			var portBase:PortBase;
			for (var i:int = 0; i < length; i++) 
			{
				if(portBase == port){
					ports.splice(i,1);
					break;
				}
			}
		}
		
		public function removePortAt(index:int):void{
			ports.splice(index,1);
		}
		
		public final function resumeGraphLayoutInvalidationOnMoveResize():void{
		
		}
		
		public final function suspendGraphLayoutInvalidationOnMoveResize():void{
		
		}
		
		protected function createDefaultPort():PortBase{
			var portBase:PortBase = new PortBase(PortPosition.CENTER,false);
			return portBase;
		}
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// override 覆盖函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		override public function clone():Renderer{
			var renderer:Renderer = super.clone();
			var node:Node = renderer as Node;
			node.label = this.label;
			return node;
		}
	}//类结束
}//包结束